#include <iostream>
#include <pthread.h>
#include <vector>
#include <unistd.h>
#include "lockGuard.hpp"
#define NUM 3
using namespace std;
int ticket = 1000;

class threadData
{
public:
    pthread_t _tid;
    string _name;
    int _gotTickets = 0; // 抢了多少张
    pthread_mutex_t *_lock;
};

// 加锁方式一：对象传参
//  void *GrabTickets(void *agrv)
//  {
//      threadData* tdata = (threadData*)agrv;
//      while(true)
//      {
//          pthread_mutex_lock(tdata->_lock);
//          if(ticket > 0)
//          {
//              usleep(1000);
//              cout<<"-------------------------------"<<endl;
//              printf("%s,get a ticket!\n",tdata->_name.c_str());
//              printf("left tickets:%d\n",ticket);
//              tdata->_gotTickets++;
//              ticket--;
//              pthread_mutex_unlock(tdata->_lock);
//          }
//          else
//          {
//              pthread_mutex_unlock(tdata->_lock);
//              break;
//          }
//          usleep(100);//模仿抢票后的操作
//      }
//      return nullptr;
//  }

// 加锁方式二：临时的LockGuard对象， RAII风格的锁！
void *GrabTickets(void *agrv)
{
    threadData *tdata = (threadData *)agrv;
    while (true)
    {
        {
            LockGuard ld = LockGuard(tdata->_lock);
            if (ticket > 0)
            {
                usleep(1000);
                cout << "-------------------------------" << endl;
                printf("%s,get a ticket!\n", tdata->_name.c_str());
                printf("left tickets:%d\n", ticket);
                tdata->_gotTickets++;
                ticket--;
            }
            else
            {
                break;
            }
        }
        usleep(100); // 模仿抢票后的操作
    }

    return nullptr;
}

int main()
{
    pthread_mutex_t lock;
    pthread_mutex_init(&lock, nullptr);
    vector<threadData *> threads;
    for (int i = 0; i < NUM; i++)
    {
        pthread_t tid;
        threadData *tdata = new threadData();
        pthread_create(&tid, nullptr, GrabTickets, tdata);
        tdata->_name = "Thread" + to_string(i);
        tdata->_tid = tid;
        tdata->_lock = &lock;
        threads.push_back(tdata);
    }

    for (auto t : threads)
    {
        pthread_join(t->_tid, nullptr);
        printf("%s grab %d tisckets\n", t->_name.c_str(), t->_gotTickets);
        delete t;
    }

    pthread_mutex_destroy(&lock);
    return 0;
}